#include <stdlib.h>
#include <string.h>
#include "util.h"
#include "parse.h"
#include "pcre.h"

/**
 * Prints the current configuration settings to screen
 *
 * @param defs pointer to the settings struct
 */
void dump_config(settings * defs) {
        printf("Report Type(s): %d\n", defs->report_types);
        printf("Output Type(s): %d\n", defs->output_format);
        printf("Filename: '%s'\n",     defs->filename);
        printf("Delimiter: '%s'\n",    defs->column_delimiter);
}

/**
 * Takes a pointer to a log file and parses it according to the provided settings
 *
 * @param lf a log_file struct with an open and readable file
 * @param parse_settings a settings struct containing the current parse and output settings
 * @return The number of lines in the
 */
int parse_log_file(log_file * lf, settings * parse_settings) {
	char * regex = PATTERN_COMBINED;
	const char * error;
	int erroffset;
	// build the output vector for the regex matches
	int ovec[PATTERN_COMBINED_OVEC_LEN];
	// clear the memory for the output vector
	memset(ovec, '\0', PATTERN_COMBINED_OVEC_LEN * sizeof(int));

	// compile the standard pattern for parsing CLF files
	pcre * pattern = pcre_compile(regex, PCRE_CASELESS, &error, &erroffset, 0);
	// study the pattern to optimize it for speed since it will be used over and over
	pcre_extra * hints = pcre_study(pattern, PCRE_CASELESS, &error);
//	pcre_extra * hints = '\0';
	if(!pattern) {
		// there was an error compiling the pattern
		fprintf(stderr,"PCRE expression could not be compiled, error at offset %d\n\tPCRE said: %s\n",erroffset,error);
		return 0;
	}

	int i = 0; // counter for the total number of lines
	int matches = 0; // counter for the total number of lines that matched the regex
	log_line * cur;
	// loop over the lines of the log file, executing the regex on all of them
	while((cur = get_line_from_file(lf))) {
		//printf("Attempting to match %d char line: \n%s\n",cur->line_length,cur->line_contents);
		int rc;
		// execute the regex on the current line from the file
		rc = pcre_exec(pattern,hints, cur->line_contents, cur->line_length,0,0, ovec, PATTERN_COMBINED_OVEC_LEN);

		if(rc > 0) // 0 or less means no matches
			++matches;

		char curbuf[1024];
		int strlen;

		strlen = pcre_copy_named_substring(pattern, cur->line_contents, ovec, rc, "request_uri", curbuf, 1024);
//		printf("Request URI: %s\n", curbuf);
		strlen = pcre_copy_named_substring(pattern, cur->line_contents, ovec, rc, "response_size", curbuf, 1024);
		long size = atoi(curbuf);
//		printf("Response Size(bytes): %ld\n", size);
		strlen = pcre_copy_named_substring(pattern, cur->line_contents, ovec, rc, "user_agent", curbuf, 1024);
//		printf("User Agent: %s\n", curbuf);
		strlen = pcre_copy_named_substring(pattern, cur->line_contents, ovec, rc, "referrer", curbuf, 1024);
//		printf("Referrer: %s\n", curbuf);
//		printf("--------------------------------------------------------------------\n\n");

//		printf("%2d: %.*s\n", j, ovec[2*j+1] - ovec[2*j], cur->line_contents + ovec[2*j]);

		// release the log line memory
		free_log_line(cur);
		++i;

//		return matches;
	}

	printf("Inspected %d lines, %d of them matched\n", i, matches);

	// release the memory for the pattern and the pcre hints
	free(pattern);
	free(hints);
	pattern = 0;
	hints   = 0;

	return matches;
}

parsed_log_entry * parse_log_line(log_line * ll) {
	parsed_log_entry * entry = (parsed_log_entry *)malloc(sizeof(parsed_log_entry));
	return '\0';
}
